import Cookies from 'js-cookie'
import { MessageBox } from 'element-ui'
import router from '@/router'
import store from '@/store'
import { isString, isArray, getUrlQuery, hasOwn, isObject } from '@web-utils/core'
import { loginPath, server, tokenInvalidateMessage, tokenInvalidateTips } from '@/config'

const TOKEN_KEY = 'fy-token'
const TWO_FACTOR_AUTH_TOKEN_KEY = '2fa-token'
let tipsShowing = false

/**
 * 登录确认
 * @returns {Promise<Error>}
 */
export async function loginConfirm(error) {
  if (getToken()) {
    // token 不为空时要弹出确认对话框
    if (!tipsShowing) {
      tipsShowing = true
      try {
        if (isAuthError(error) && error.url.indexOf('admin/user/info') > -1) {
          await MessageBox.alert(tokenInvalidateTips, '系统提示', {
            closeOnHashChange: false,
            type: 'warning',
            showClose: false
          })
        } else {
          await MessageBox.confirm(tokenInvalidateMessage, '系统提示', {
            type: 'warning',
            closeOnClickModal: false,
            closeOnHashChange: false
          })
        }
        store.commit('im/hideChatWindow')
        store.commit('user/reset')
        await toLogin()
      } catch (_) {}
      tipsShowing = false
    }
  } else {
    await toLogin()
  }
  return Promise.reject(error)
}

export class UnAuthError extends Error {
  constructor(message, url) {
    super(message)
    this.url = url
  }
}

export const isAuthError = e => e instanceof UnAuthError

/**
 * 记录 hash 并跳转到登录页
 * @returns {Promise<void>}
 */
async function toLogin() {
  const query = getUrlQuery(window.location.href)
  if (!hasOwn(query, 'redirect')) {
    let hash = window.location.hash.substring(1, location.hash.length)
    hash = hash === `/${loginPath}` ? '' : hash
    let redirect = window.location.href
    redirect = redirect.indexOf(`/${loginPath}`) > -1 ? server : redirect
    localStorage.setItem('redirect', redirect)
    await router.replace({ path: `/${loginPath}`, query: { redirect: hash } })
  } else {
    await router.replace({ path: `/${loginPath}` })
  }
}

/**
 * 设置 token
 * @param {String} token token
 * @param {Boolean} auto 是否自动过期
 */
export const setToken = (token = '', auto = true) => Cookies.set(TOKEN_KEY, token, auto ? { expires: 1 } : {})

export const set2FAToken = (token = '', auto = true) => Cookies.set(TWO_FACTOR_AUTH_TOKEN_KEY, token, auto ? { expires: 1 } : {})

/**
 * 清除 token
 */
export const clearToken = () => Cookies.set(TOKEN_KEY, '')

export const clear2FAToken = () => Cookies.set(TWO_FACTOR_AUTH_TOKEN_KEY, '')

/**
 * 获取token
 * @returns {String}
 */
export const getToken = () => Cookies.get(TOKEN_KEY)

export const get2FAToken = () => Cookies.get(TWO_FACTOR_AUTH_TOKEN_KEY)

/**
 * 判断用户是否有指定的权限
 * @param {String,Array<String>} authority 用户权限,字符串或数组
 */
export const hasAuthority = authority => {
  const permissions = store.state.user.permissions
  if (isString(authority)) {
    return permissions[authority] === true
  }
  if (isArray(authority)) {
    return authority.every(value => permissions[value] === true)
  }
  return false
}

export const processButtons = buttons => {
  return buttons.map(value => {
    if (isObject(value)) {
      for (const valueKey in value) {
        if (isString(value[valueKey])) {
          value[valueKey] = hasAuthority(value[valueKey])
        }
      }
    }
    return value
  })
}
